package sieve_task_aggregation

import (
	"context"
	"fmt"
	"github.com/google/wire"
	"reflect"
	"sieve_admin_server_userpass/app/dao/util"
	"sieve_admin_server_userpass/app/schema"
	"sieve_admin_server_userpass/lib/mysql"
	"strings"
	"time"
)

var (
	SieveTaskAggregationSet = wire.NewSet(wire.Struct(new(SieveTaskAggregationRepo), "*"))
)

type SieveTaskAggregationRepo struct {
	DB *mysql.DB
}

func (a *SieveTaskAggregationRepo) Create(ctx context.Context, items map[string]interface{}) error {

	_, err := util.Create(ctx, SieveTaskAggregation{}.TableName(), a.DB, items)
	return err
}

func (a *SieveTaskAggregationRepo) SoftDelete(ctx context.Context, id uint64) error {

	var (
		now        = time.Now().Unix()
		updateKeys = map[string]interface{}{
			"deleted":    1,
			"updated_at": now,
		}
		queryKeys = map[string]interface{}{
			"id": id,
		}
	)
	return a.update(ctx, updateKeys, queryKeys)
}

func (a *SieveTaskAggregationRepo) update(ctx context.Context, updateKeys map[string]interface{}, queryKeys map[string]interface{}) error {

	var (
		db               = a.DB
		values           []interface{}
		tableName        = SieveTaskAggregation{}.TableName()
		updates, queries []string
	)

	for k, v := range updateKeys {

		vv := v
		if reflect.TypeOf(v).Kind() == reflect.String {
			vv = fmt.Sprintf("'%v'", v)
		}
		updates = append(updates, fmt.Sprintf("%v = %v", k, vv))
	}

	for k, v := range queryKeys {

		vv := v
		if reflect.TypeOf(v).Kind() == reflect.String {
			vv = fmt.Sprintf("'%v'", v)
		}
		queries = append(queries, fmt.Sprintf("%v = %v", k, vv))
	}

	updateSQL := fmt.Sprintf("UPDATE %s SET %v WHERE %v",
		tableName,
		strings.Join(updates, ","),
		strings.Join(queries, " AND "),
	)

	_, err := db.Exec(updateSQL, values...)
	return err
}

func (a *SieveTaskAggregationRepo) UpdateSieveFile(ctx context.Context, sieveFile string) error {

	return a.Update(ctx, map[string]interface{}{
		"sieve_file": sieveFile,
	}, nil)
}

func (a *SieveTaskAggregationRepo) Update(ctx context.Context, reqArgs map[string]interface{}, repKeys map[string]interface{}) error {

	return util.Update(ctx, SieveTaskAggregation{}.TableName(), a.DB, reqArgs, repKeys)
}

func (a *SieveTaskAggregationRepo) Query(ctx context.Context, reqArgs map[string]interface{}, p schema.PaginationParam, repKeys []string) (interface{}, error) {

	return util.Query(ctx, SieveTaskAggregation{}, a.DB, reqArgs, p, repKeys)
}

func (a *SieveTaskAggregationRepo) QueryRaw(ctx context.Context, querySQL string, out interface{}) ([]interface{}, error) {

	return util.QueryRaw(ctx, a.DB, querySQL, out)
}
